import configs
from fuzzywuzzy import fuzz
from utils import service_functions
from template.singleton import Singleton


class Decoders(Singleton):
    def search_name(self, cmd: str):
        # Активация по имени
        probMax = configs.probability_cmd
        __word = ""
        # Разбиение строки на список
        list_cmd = cmd.split(" ")
        for str_cmd in configs.cmds["name"]:
            # print(str_cmd)
            for l_cmd in list_cmd:
                # try:

                # par = 100 / len(l_cmd)
                # print(par,configs.PROBABILITY_CMD_CONST)
                # Узнаём цену одного символа 100/длину строки
                # booleen = int(par + configs.PROBABILITY_CMD_CONST) <= 100
                # print(booleen)
                # Если цена сивола + пороговое значение активации <=100 то True
                # Например 100/len(Три)=33,3
                # probability_cmd_name = 75
                # 33,3+probability_cmd_name 75+33,3 = 108,3 False
                # if booleen:
                # print(booleen)
                Levenshtein_d = fuzz.ratio(l_cmd, str_cmd)
                service_functions.fuzz_word_cheek(len(str_cmd))
                if Levenshtein_d >= configs.probability_cmd:
                    # print(222444)
                    """Если что оптимизировать"""
                    # Максимальное совпадение имени с распознаными
                    # словами
                    if Levenshtein_d > probMax:
                        probMax = Levenshtein_d
                        __word = str_cmd
                    elif Levenshtein_d == probMax:
                        __word = str_cmd
            # except BaseException:
            #    print("Опа")
        # if __word == '':
        #    return ''
        # print(__word, len(__word))
        return __word

    # Распознование меток
    def function_recognition(self, cmd: str, json_name: str) -> list:
        function_name = []
        if len(cmd) != 0:
            for key, values in configs.cmds[json_name].items():
                for value in values:
                    service_functions.fuzz_word_cheek(len(value))
                    Levenshtein_d = fuzz.partial_ratio(cmd, value)
                    if Levenshtein_d >= configs.probability_cmd:
                        __word = key
                        if not __word:
                            return []
                        elif __word:
                            if configs.one_func:
                                return [__word]
                            elif not configs.one_func:
                                # if increase_accuracy_factor==True:
                                # probability= Levenshtein_d
                                function_name.append(__word)
                                break
        if len(function_name) == 0:
            return []
        return function_name

    def search_cmd(self, cmd: str, json_name: str = "void") -> list:
        # def dec_function_recognition_glav(self, cmd: str, json_name: str = "void") -> list:
        function_name = []
        if len(cmd) != 0:
            for key, values in configs.cmds[json_name].items():
                for value in values["word_list"]:
                    service_functions.fuzz_word_cheek(len(value))
                    Levenshtein_d = fuzz.partial_ratio(cmd, value)
                    if Levenshtein_d >= configs.probability_cmd:
                        __word = key
                        if len(__word) == 0:
                            return []
                        elif len(__word) > 0:
                            if configs.one_func:
                                return [__word]
                            elif not configs.one_func:
                                # if increase_accuracy_factor==True:
                                # probability= Levenshtein_d
                                function_name.append(__word)
                                break
        if len(function_name) == 0:
            return []
        return function_name

    # def dec_function_recognition_keys(self, cmd: str, json_key_str: str) -> str:
    def search_key_cmd(self, cmd: str, json_key_str: str) -> str:
        __word = ""
        len_str_cmd = len(cmd)
        if len_str_cmd != 0:
            par = 100 / len_str_cmd
            booleen = int(par + configs.PROBABILITY_CMD_CONST) <= 100
            if booleen:
                if len_str_cmd != 0:
                    for keys, values in configs.cmds[json_key_str].items():
                        for value in values:
                            service_functions.fuzz_word_cheek(len(value))
                            Levenshtein_d = fuzz.partial_ratio(cmd, value)
                            if Levenshtein_d >= configs.probability_cmd:
                                __word = keys
                                if not __word:
                                    return ""
                                elif __word:
                                    __word = keys
                if __word:
                    return __word
                else:
                    return ""
            else:
                for key, values in configs.cmds[json_key_str].items():
                    for value in values:
                        if cmd == value:
                            return key
                        else:
                            pass
                return ""
        else:
            return ""

    # def dec_recognition_value(self, cmd: str, json_name_key: str) -> str:
    def search_value_cmd(self, cmd: str, json_name_key: str) -> str:
        __word = ""
        par = 100 / len(cmd)
        booleen = int(par + configs.PROBABILITY_CMD_CONST) <= 100
        if booleen:
            if cmd:
                for keys, values in configs.cmds[json_name_key].items():
                    for value in values:
                        service_functions.fuzz_word_cheek(len(value))
                        Levenshtein_d = fuzz.partial_ratio(cmd, value)
                        if Levenshtein_d >= configs.probability_cmd:
                            __word = value
                            if not __word:
                                return ""
                            elif __word:
                                __word = value
            if __word:
                return __word
            else:
                return ""
        else:
            for key, values in configs.cmds[json_name_key].items():
                for value in values:
                    if cmd == value:
                        return value
                    else:
                        pass
            return ""

    # def decoder_titles(self, voice_cmd: str, list_titles: list) -> int:
    # Поменять название на нормальное !!!
    def decoder_titles(self, voice_cmd: str, list_titles: list) -> int:
        __count_index = 0
        par = 100 / len(voice_cmd)
        booleen = int(par + configs.probability_cmd) <= 100
        if booleen:
            for index, titles in enumerate(list_titles):
                service_functions.fuzz_word_cheek(len(titles))
                Levenshtein_d = fuzz.partial_ratio(voice_cmd, titles)
                if Levenshtein_d >= configs.probability_cmd:
                    __count_index = index
            return __count_index
        else:
            for index, titles in enumerate(list_titles):
                if voice_cmd == titles:
                    return __count_index
                else:
                    return -1
